﻿using System.IO;
using System.IO.IsolatedStorage;
using System.Text;

namespace JasonTools 
{
    public static class IsolatedStorageHelper
    {
        /// <summary>
        /// Get value of a setting item.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static object GetSetting(string key)
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
            {
                return IsolatedStorageSettings.ApplicationSettings[key];
            }
            return null;
        }

        /// <summary>
        /// Set value of a setting item.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void SetSetting(string key, object value)
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
            {
                IsolatedStorageSettings.ApplicationSettings[key] = value;
            }
            else
            {
                IsolatedStorageSettings.ApplicationSettings.Add(key, value);
            }
            IsolatedStorageSettings.ApplicationSettings.Save();
        }

        /// <summary>
        /// Save a single file to the isolated storage.
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="content"></param>
        public static void SaveFile(string filePath, byte[] content)
        {
            using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (isf.FileExists(filePath))
                {
                    using (var fs = isf.OpenFile(filePath, FileMode.Open, FileAccess.Write, FileShare.None))
                    {
                        fs.Write(content, 0, content.Length);
                        //Using blocks are currently not guaranteed to flush/close streams in WP7. 
                        fs.Flush();
                        fs.Close();
                    }
                }
                else
                {
                    using (IsolatedStorageFileStream fs = isf.CreateFile(filePath))
                    {
                        fs.Write(content, 0, content.Length);
                        fs.Flush();
                        fs.Close();
                    }
                }
            }
        }

        /// <summary>
        /// Save a single text file, encode in UTF-8.
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="content"></param>
        public static void SaveFile(string filePath, string content)
        {
            SaveFile(filePath, Encoding.UTF8.GetBytes(content));
        }

        /// <summary>
        /// Open a single file to read.
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns>Null if not exists.</returns>
        /// <remarks>You MUST call Flush() and Close() MANUALLY. It's not guaranteed that Using statement will release resources in the current version of sdk.</remarks>
        public static IsolatedStorageFileStream OpenRead(string filePath)
        {
            var isf = IsolatedStorageFile.GetUserStoreForApplication();
            if (!isf.FileExists(filePath))
            {
                isf.Dispose();
                return null;
            }
            return isf.OpenFile(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
        }

        /// <summary>
        /// Read all text of a single file.
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static string ReadAllText(string filePath)
        {
            var isf = IsolatedStorageFile.GetUserStoreForApplication();
            if (!isf.FileExists(filePath))
            {
                isf.Dispose();
                return null;
            }
            string fileContent;
            using (IsolatedStorageFileStream fs = isf.OpenFile(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (StreamReader reader = new StreamReader(fs))
                {
                    fileContent = reader.ReadToEnd();
                }
            }
            isf.Dispose();
            return fileContent;
        }

        /// <summary>
        /// Read all bytes of a single file.
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static byte[] ReadAllBytes(string filePath)
        {
            var isf = IsolatedStorageFile.GetUserStoreForApplication();
            if (!isf.FileExists(filePath))
            {
                isf.Dispose();
                return null;
            }
            byte[] fileContent;
            using (IsolatedStorageFileStream fs = isf.OpenFile(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                fileContent = new byte[fs.Length];
                fs.Read(fileContent, 0, (int)fs.Length);
                fs.Flush();
                fs.Close();
            }
            isf.Dispose();
            return fileContent;
        }

        /// <summary>
        /// Create given directory
        /// </summary>
        /// <param name="path"></param>
        public static void CreateDirectory(string path)
        {
            using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!isf.DirectoryExists(path))
                {
                    isf.CreateDirectory(path);
                }
            }
        }

        /// <summary>
        /// Open a single file to write.
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns>Null if not exists.</returns>
        /// <remarks>You MUST call Flush() and Close() MANUALLY. It's not guaranteed that Using statement will release resources in the current version of sdk.</remarks>
        public static Stream OpenWrite(string filePath)
        {
            var isf = IsolatedStorageFile.GetUserStoreForApplication();
            if (isf.FileExists(filePath))
            {
                return isf.OpenFile(filePath, FileMode.Open, FileAccess.Write, FileShare.None);
            }
            return isf.CreateFile(filePath);
        }

        /// <summary>
        /// Delete a single file if exists.
        /// </summary>
        /// <param name="filePath"></param>
        public static void DeleteFile(string filePath)
        {
            using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (isf.FileExists(filePath))
                {
                    isf.DeleteFile(filePath);
                }
            }
        }

        /// <summary>
        /// Check is file exists.
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static bool IsFileExists(string filePath)
        {
            using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
            {
                return isf.FileExists(filePath);
            }
        }

    }
}
